import { useAccessStore, useOAuth2Store } from "@scpun/stores";
import { Router } from "vue-router";
import { PageEnum } from "../enums/page";
import { accessRoutes, coreRouteNames } from "../routes";
import { generateAccess } from "./access";

export const setupAuthGuard = (router: Router) => {
    router.beforeEach(async (to, from) => {
        const accessStore = useAccessStore();
        const oauth2Store = useOAuth2Store();
        // 基本路由，这些路由不需要进入权限拦截
        if (coreRouteNames.includes(to.name as string)) {
            if (to.path === PageEnum.LOGIN_PATH && accessStore.accessToken) {
                return decodeURIComponent((to.query?.redirect as string) || PageEnum.HOME_PATH);
            }
            return true;
        }

        // accessToken 检查
        if (!accessStore.accessToken) {
            // 明确声明忽略权限访问权限，则可以访问
            if (to.meta.ignoreAccess) {
                return true;
            }

            // 没有访问权限，跳转登录页面
            if (to.path !== PageEnum.LOGIN_PATH) {
                return {
                    path: PageEnum.LOGIN_PATH,
                    // 如不需要，直接删除 query
                    query: { redirect: encodeURIComponent(to.fullPath) },
                    // 携带当前跳转的页面，登录后重新跳转该页面
                    replace: true,
                };
            }
            return to;
        }

        // 是否已经生成过动态路由
        if (accessStore.isAccessChecked) {
            return true;
        }
        // 生成路由表
        const userRoles = oauth2Store.storeRoles;

        // 生成菜单和路由
        const { accessibleMenus, accessibleRoutes } = await generateAccess({
            roles: userRoles,
            router,
            // 则会在菜单中显示，但是访问会被重定向到403
            routes: accessRoutes,
        });

        // 保存菜单信息和路由信息
        accessStore.setAccessMenus(accessibleMenus);
        accessStore.setAccessRoutes(accessibleRoutes);
        accessStore.setIsAccessChecked(true);

        const redirectPath = (from.query.redirect ?? to.fullPath) as string;

        return {
            ...router.resolve(decodeURIComponent(redirectPath)),
            replace: true,
        };
    });
};
